// 便捷化控制台打印函数
var Log = function() {
    console.log.apply(console, arguments);
}

// Todo是否是已完成状态
var hasDone = el => {
    return (el.querySelector('.icon-undo').innerText != "");
}

// 显示tools
var showTools = el => {
    let todoLi = el.parentNode.parentNode;
    let menu = todoLi.querySelector(".todo-menutool");
    menu.style.display = menu.style.display == "block" ? "none": "block";
}

// 关闭tools 
var closeTools = el => {
    el.parentNode.parentNode.style.display = "none";
}

// 提示消息
var tipMsg = msg => {
    let tipNode = document.querySelector('.tip')
    tipNode.style.display = "block";
    tipNode.querySelector('.tip-text').innerText = msg;
    setInterval(() => {tipNode.style.display = "none";}, 2000);
}

// 关闭提示消息
var deleteTip = el => {
    el.parentNode.style.display = "none";
}

// 格式化某一li
var liToJson = (liNode, index) => {
    let rs = {
        pos: '',
        hasDone: '',
        todoText: '',
        importance: ''
    }
    rs.importance = liNode.getAttribute('data-grd');
    rs.hasDone = hasDone(liNode);
    rs.todoText = liNode.querySelector('.todo-text').innerText;
    rs.pos = index;
    return JSON.stringify(rs);
}

// 格式化整个页面（Ul）
var ulToJson = () => {
    let ulNode = document.querySelector('.todo-ul');
    // 设定数据存储格式
    let rs = {
        total: 0,
        data: []
    };
    // 遍历格式化所有Todo
    ulNode.querySelectorAll('li').forEach((item, index) => {
        rs.data.push(liToJson(item, index));
        rs.total += 1;
    });
    return JSON.stringify(rs);
}

// 获得当前li在ul中的位置，位置从0开始
var getIndexOfLi = el => {
    let ulNode= el.parentNode;
    let index = 0;
    ulNode.querySelectorAll('li').forEach((li, i) => {
        if (li == el) {
            index = i;
            return;
        }
    });
    return index;
}

//存储数据到LocalStorage
var saveData = () => {localStorage.setItem('data', ulToJson());}

// 从LocalStorage读取数据 
var readData = () => {return localStorage.getItem('data');}

// 反序列化
var jsonToObject = jsonStr => {return JSON.parse(jsonStr)};

// 注入数据到模板，返回注入后的字符串
var injectData = data => {
    let tmpl = document.querySelector("#tmpl").innerText;
    tmpl = tmpl.replace(/\$\{(\w+)\}/g, (match, key) => {return data[key]});
    return tmpl;
}

// 将模板字符串建立成一个Li节点，并返回
var createNewLiNodeFromTemplate = tmpl => {
    let newLi = document.createElement("div");
    newLi.innerHTML = tmpl;
    newLi = newLi.querySelector("li");
    return newLi;
} 

// 进入编辑状态
var intoEditState = (todoContent, todoLiPos, el) => {
    let todoIpt = document.querySelector("#todo-ipt");
    let todoBtn = document.querySelector("#todo-btn");
    todoIpt.value = todoContent;
    todoIpt.focus();
    todoBtn.innerText = `修 改`;
    todoBtn.setAttribute("onclick", `ChangeTodo(this, ${todoLiPos})`); // 编辑状态下，按钮的onclick函数发生变化。
    // 关闭tools
    closeTools(el);
    // 创建遮罩
    let hideEl = document.createElement("div");
    hideEl.setAttribute("class", "hideElement")
    document.querySelector(".todo-ul").appendChild(hideEl);
}

// 退出编辑状态
var exitEditState = el => {
    let hideEl = document.querySelector(".hideElement");
    // 恢复按钮文字
    el.innerText = `发 布`;
    // 恢复按钮点击事件
    el.setAttribute('onclick', 'submitTodo()');
    // 清空输入框
    document.querySelector("#todo-ipt").value = '';
    // 移除遮罩
    hideEl != null &&  hideEl.parentElement.removeChild(hideEl);
}

// 修改重要性等级
var changeImportance = (el, flag) => {
    let todoLi = el.parentNode.parentNode.parentNode;
    let todoText = todoLi.querySelector(".todo-text");
    todoLi.setAttribute("data-grd", flag);
    if(hasDone(todoLi)) return; // 完成状态下，不能修改文字颜色
    if(flag == 1) {
        todoText.style.color = "red";
    } else if (flag == 2) {
        todoText.style.color = "orange";
    } else {
        todoText.style.color = "white";
    }
    closeTools(el);
    saveData();
}

// 完成Todo
var Done = el => {
    let todoLi = el.parentNode.parentNode;
    let todoText = todoLi.querySelector(".todo-text");
    if(hasDone(todoLi)) {
        // 已完成 -> 未完成
        el.innerText = "";
        changeImportance(todoLi.querySelector('.colors-white'), todoLi.getAttribute('data-grd'));
        todoText.style.textDecoration = "none";
    } else {
        // 未完成 -> 已完成
        el.innerText = "√";
        todoText.style.textDecoration = "line-through";
        todoText.style.color = "gray";
    }
    saveData();
}


// 插入数据到某一Todo（LiNode）前
var insertNewTodoFromData = (data, nextLiNode=null) => {
    // 建立Li节点
    let newLi = createNewLiNodeFromTemplate(injectData(data));
    // 插入Li节点到文档流中
    newLi = document.querySelector(".todo-ul").insertBefore(newLi, nextLiNode);  
    // Log("newLI: ", newLi);
    // 完成任务
    data.hasDone && (Done(newLi.querySelector('.icon-undo')));
    // 修改重要性
    changeImportance(newLi.querySelector('.colors-white'), data.importance);
    // 进行了实质性修改，均需保存数据
    saveData();
}



/* ----------【增】---------- */
// 新增Todo
var addTodo = data => {
    insertNewTodoFromData(data, document.querySelector('.todo-ul').querySelector('li'));
}

// 提交一个新的Todo
var submitTodo = () => {
    let todoContent = document.querySelector('#todo-ipt').value;
    let newData = {
        pos: 0,
        hasDone: false,
        todoText: todoContent,
        importance: 3
    }
    // 清空输入框
    document.querySelector('#todo-ipt').value = '';
    addTodo(newData);
    tipMsg('发布成功！');
}

/* ----------【删】---------- */
// 删除一个Todo
var deleteTodo = (el) => {
    let liNode = el.parentNode.parentNode.parentNode;
    // 找到父级节点后删除
    liNode.parentNode.removeChild(liNode);
    // 进行了实质性修改，均需保存数据
    saveData();
    tipMsg('删除成功！');
}

/* ----------【改】---------- */
// 编辑todo(未修改实际Todo)
var editTodo = el => {
    let todoLi = el.parentNode.parentNode.parentNode;
    // 获取要编辑的Todo内容
    let todoContent = todoLi.querySelector(".todo-text").innerText;
    // 计算该 li 的位置
    let pos = getIndexOfLi(todoLi);
    // 进入编辑状态
    intoEditState(todoContent, pos, el);
}

// 修改Todo（实际修改了Todo）
var ChangeTodo = (el, pos) => {
    // 修改Todo
    let newTodoContent = document.querySelector("#todo-ipt").value;
    let todoUl = document.querySelector(".todo-ul");
    let todoLi = todoUl.querySelectorAll("li")[pos];
    todoLi.querySelector(".todo-text").innerText = newTodoContent;
    // 退出编辑状态
    exitEditState(el);
    // 进行了实质性修改，均需保存数据
    saveData();
    tipMsg("修改成功!");
}   

// 上移一个Todo
var upTodo = el => {
    let liNode = el.parentNode.parentNode.parentNode;
    let ulNode = document.querySelector('.todo-ul');
    let index = getIndexOfLi(liNode);
    index = index - 1 < 0 ? 0 : index - 1;
    // if (index < 1) {return;}
    ulNode.insertBefore(liNode, ulNode.querySelectorAll('li')[index]);
    closeTools(el);
    saveData();
}

// 置顶
var topTodo = el => {
    let liNode = el.parentNode.parentNode.parentNode;
    let ulNode = liNode.parentNode;
    // Log("topTodo-", "ulNode: ", ulNode);
    ulNode.insertBefore(liNode, ulNode.firstChild);
    closeTools(el);
    saveData();
}

// 下移一个Todo
var downTodo = el => {
    let liNode = el.parentNode.parentNode.parentNode;
    let ulNode = document.querySelector('.todo-ul');
    let index = getIndexOfLi(liNode);
    let maxIndex = ulNode.querySelectorAll('li').length;
    index = index + 2 > maxIndex ? maxIndex : index + 2; 
    ulNode.insertBefore(liNode, ulNode.querySelectorAll('li')[index]);
    closeTools(el);
    saveData();
}

// 置底
var floorTodo = el => {
    let liNode = el.parentNode.parentNode.parentNode;
    let ulNode = document.querySelector('.todo-ul');
    let maxIndex = ulNode.querySelectorAll('li').length;
    ulNode.insertBefore(liNode, ulNode.querySelectorAll('li')[maxIndex]);
    closeTools(el);
    saveData();
}

/* ----------【查】---------- */
// 初始化，从LocalStorage读取数据，创建页面
var init = () => {
    // 确保LocalStorage里有一份数据，防止读取出的数据为null
    readData() == null && saveData();
    // 读取数据
    let data = jsonToObject(readData());
    // 遍历构建节点
    data.data.forEach(item => {
        let tempData = jsonToObject(item);
        insertNewTodoFromData(tempData);
    })
}

init();